package com.example.androidproject;

import android.os.AsyncTask;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

public class ApiClient {

    private static final String BASE_URL = "http://114.215.189.90:6666/";

    public interface ApiCallback<T> {
        void onSuccess(T result);

        void onError(String error);
    }

    public static void login(String username, String password, ApiCallback<Boolean> callback) {
        new LoginTask(username, password, callback).execute();
    }

    public static void register(String username, String password, ApiCallback<Boolean> callback) {
        new RegisterTask(username, password, callback).execute();
    }

    public static void getBooks(ApiCallback<List<Book>> callback) {
        new GetBooksTask(callback).execute();
    }

    public static void getBorrowRecords(ApiCallback<List<String>> callback) {
        new GetBorrowRecordsTask(callback).execute();
    }

    public static void getPersonalInfo(String username, ApiCallback<JSONObject> callback) {
        new GetPersonalInfoTask(username, callback).execute();
    }

    public static void updateBookStatus(int bookId, String newStatus, String username, ApiCallback<Boolean> callback) {
        new UpdateStatusTask(bookId, newStatus, username, callback).execute();
    }

    public static void addBook(String title, String author, String category, String publishDate,
            String backgroundStory, ApiCallback<Boolean> callback) {
        new AddBookTask(title, author, category, publishDate, backgroundStory, callback).execute();
    }

    private static class AddBookTask extends AsyncTask<Void, Void, Boolean> {
        private final String title, author, category, publishDate, backgroundStory;
        private final ApiCallback<Boolean> callback;
        private Exception exception;
        private String serverResponse;

        AddBookTask(String title, String author, String category, String publishDate,
                    String backgroundStory, ApiCallback<Boolean> callback) {
            this.title = title;
            this.author = author;
            this.category = category;
            this.publishDate = publishDate;
            this.backgroundStory = backgroundStory;
            this.callback = callback;
        }

        @Override
        protected Boolean doInBackground(Void... voids) {
            HttpURLConnection conn = null;
            try {
                String query = String.format("title=%s&author=%s&category=%s&publishDate=%s&backgroundStory=%s",
                        URLEncoder.encode(title, "UTF-8"),
                        URLEncoder.encode(author, "UTF-8"),
                        URLEncoder.encode(category, "UTF-8"),
                        URLEncoder.encode(publishDate, "UTF-8"),
                        URLEncoder.encode(backgroundStory, "UTF-8"));

                URL url = new URL(BASE_URL + "add_book?" + query);

                Log.d("AddBook", "请求URL: " + url.toString());

                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(10000);

                int responseCode = conn.getResponseCode();
                Log.d("AddBook", "响应码: " + responseCode);

                InputStream inputStream = conn.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                serverResponse = response.toString();
                Log.d("AddBook", "服务器响应: " + serverResponse);

                if (responseCode == 200) {
                    JSONObject jsonObject = new JSONObject(serverResponse);
                    return jsonObject.getBoolean("success");
                } else {
                    throw new Exception("HTTP错误码: " + responseCode);
                }
            } catch (Exception e) {
                exception = e;
                Log.e("AddBook", "添加书籍错误", e);
                return false;
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
        }

        @Override
        protected void onPostExecute(Boolean success) {
            if (success) {
                callback.onSuccess(true);
            } else {
                String errorMsg = "添加失败";
                if (exception != null) {
                    errorMsg += ": " + exception.getMessage();
                }
                if (serverResponse != null) {
                    errorMsg += " | 响应: " + serverResponse;
                }
                callback.onError(errorMsg);
            }
        }
    }

    private static class UpdateStatusTask extends AsyncTask<Void, Void, Boolean> {
        private final int bookId;
        private final String newStatus;
        private final String username;
        private final ApiCallback<Boolean> callback;
        private Exception exception;

        UpdateStatusTask(int bookId, String newStatus, String username, ApiCallback<Boolean> callback) {
            this.bookId = bookId;
            this.newStatus = newStatus;
            this.username = username;
            this.callback = callback;
        }

        @Override
        protected Boolean doInBackground(Void... voids) {
            HttpURLConnection conn = null;
            try {
                URL url = new URL(
                        BASE_URL + "update_status?id=" + bookId + "&status=" + newStatus + "&username=" + username);
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);

                int responseCode = conn.getResponseCode();
                if (responseCode == 200) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    JSONObject jsonObject = new JSONObject(response.toString());
                    return jsonObject.getBoolean("success");
                }
                return false;
            } catch (Exception e) {
                exception = e;
                return false;
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
        }

        @Override
        protected void onPostExecute(Boolean success) {
            if (success) {
                callback.onSuccess(true);
            } else {
                callback.onError(exception != null ? exception.getMessage() : "Update failed");
            }
        }
    }

    private static class LoginTask extends AsyncTask<Void, Void, Boolean> {
        private final String username;
        private final String password;
        private final ApiCallback<Boolean> callback;
        private Exception exception;

        LoginTask(String username, String password, ApiCallback<Boolean> callback) {
            this.username = username;
            this.password = password;
            this.callback = callback;
        }

        @Override
        protected Boolean doInBackground(Void... voids) {
            HttpURLConnection conn = null;
            try {
                URL url = new URL(BASE_URL + "login?username=" + username + "&password=" + password);
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);

                InputStream inputStream = conn.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }

                JSONObject jsonObject = new JSONObject(response.toString());
                return jsonObject.getBoolean("success");
            } catch (Exception e) {
                exception = e;
                return false;
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
        }

        @Override
        protected void onPostExecute(Boolean success) {
            if (success) {
                System.out.println("[LOGIN_SUCCESS] User logged in successfully: " + username);
                callback.onSuccess(true);
            } else {
                System.out.println("[LOGIN_FAILED] Login failed for user: " + username + ", Error: "
                        + (exception != null ? exception.getMessage() : "Login failed"));
                callback.onError(exception != null ? exception.getMessage() : "Login failed");
            }
        }
    }

    private static class RegisterTask extends AsyncTask<Void, Void, Boolean> {
        private final String username;
        private final String password;
        private final ApiCallback<Boolean> callback;
        private Exception exception;

        RegisterTask(String username, String password, ApiCallback<Boolean> callback) {
            this.username = username;
            this.password = password;
            this.callback = callback;
        }

        @Override
        protected Boolean doInBackground(Void... voids) {
            HttpURLConnection conn = null;
            try {
                URL url = new URL(BASE_URL + "register?username=" + username + "&password=" + password);
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);

                InputStream inputStream = conn.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }

                JSONObject jsonObject = new JSONObject(response.toString());
                return jsonObject.getBoolean("success");
            } catch (Exception e) {
                exception = e;
                return false;
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
        }

        @Override
        protected void onPostExecute(Boolean success) {
            if (success) {
                System.out.println("[REGISTRATION_SUCCESS] User registered successfully: " + username);
                callback.onSuccess(true);
            } else {
                System.out.println("[REGISTRATION_FAILED] Registration failed for user: " + username + ", Error: "
                        + (exception != null ? exception.getMessage() : "Registration failed"));
                callback.onError(exception != null ? exception.getMessage() : "Registration failed");
            }
        }
    }

    private static class GetBooksTask extends AsyncTask<Void, Void, String> {
        private final ApiCallback<List<Book>> callback;
        private Exception exception;

        GetBooksTask(ApiCallback<List<Book>> callback) {
            this.callback = callback;
        }

        @Override
        protected String doInBackground(Void... voids) {
            HttpURLConnection conn = null;
            try {
                URL url = new URL(BASE_URL + "books");
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);

                InputStream inputStream = conn.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                return response.toString();
            } catch (Exception e) {
                exception = e;
                return null;
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
        }

        @Override
        protected void onPostExecute(String result) {
            if (result == null) {
                callback.onError(exception != null ? exception.getMessage() : "Network error");
                return;
            }

            try {
                List<Book> books = new ArrayList<Book>();
                JSONArray jsonArray = new JSONArray(result);
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject obj = jsonArray.getJSONObject(i);
                    int id = obj.getInt("id");
                    String title = obj.getString("title");
                    String author = obj.getString("author");
                    String category = obj.getString("category");
                    String publishDate = obj.getString("publishDate");
                    String status = obj.getString("status");
                    String coverResIdStr = obj.getString("coverResId");
                    String backgroundStory = obj.optString("backgroundStory", "");
                    String content = obj.optString("content", ""); // 新增内容字段

                    int coverResId = getCoverResourceId(coverResIdStr);

                    String description = obj.optString("description", "");
                    String isbn = obj.optString("isbn", "");
                    String publisher = obj.optString("publisher", "");
                    int pageCount = obj.optInt("pageCount", 0);

                    books.add(new Book(id, title, author, category, publishDate, status,
                            coverResId, description, isbn, publisher, pageCount,
                            backgroundStory, content)); // 添加content参数
                }
                callback.onSuccess(books);
            } catch (Exception e) {
                callback.onError("Data parsing error: " + e.getMessage());
                Log.e("GetBooksTask", "Error parsing JSON: " + result, e);
            }
        }

        private int getCoverResourceId(String coverResId) {
            if ("book_android".equals(coverResId)) return R.drawable.book_android;
            else if ("book_java".equals(coverResId)) return R.drawable.book_java;
            else if ("book_data".equals(coverResId)) return R.drawable.book_data;
            return R.drawable.book_default;
        }
    }

    public static void getBookContent(int bookId, ApiCallback<String> callback) {
        new GetBookContentTask(bookId, callback).execute();
    }

    private static class GetBookContentTask extends AsyncTask<Void, Void, String> {
        private final int bookId;
        private final ApiCallback<String> callback;
        private Exception exception;

        GetBookContentTask(int bookId, ApiCallback<String> callback) {
            this.bookId = bookId;
            this.callback = callback;
        }

        @Override
        protected String doInBackground(Void... voids) {
            HttpURLConnection conn = null;
            try {
                URL url = new URL(BASE_URL + "book_content?id=" + bookId);
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);

                InputStream inputStream = conn.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }

                JSONObject jsonObject = new JSONObject(response.toString());
                return jsonObject.getString("content");
            } catch (Exception e) {
                exception = e;
                return null;
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
        }

        @Override
        protected void onPostExecute(String result) {
            if (result != null) {
                callback.onSuccess(result);
            } else {
                callback.onError(exception != null ? exception.getMessage() : "Failed to load content");
            }
        }
    }

    private static class GetBorrowRecordsTask extends AsyncTask<Void, Void, String> {
        private final ApiCallback<List<String>> callback;
        private Exception exception;

        GetBorrowRecordsTask(ApiCallback<List<String>> callback) {
            this.callback = callback;
        }

        @Override
        protected String doInBackground(Void... voids) {
            HttpURLConnection conn = null;
            try {
                URL url = new URL(BASE_URL + "borrow_records");
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);

                InputStream inputStream = conn.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                return response.toString();
            } catch (Exception e) {
                exception = e;
                return null;
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
        }

        @Override
        protected void onPostExecute(String result) {
            if (result == null) {
                callback.onError(exception != null ? exception.getMessage() : "Network error");
                return;
            }

            try {
                List<String> records = new ArrayList<String>();
                JSONArray jsonArray = new JSONArray(result);
                for (int i = 0; i < jsonArray.length(); i++) {
                    records.add(jsonArray.getString(i));
                }
                callback.onSuccess(records);
            } catch (JSONException e) {
                callback.onError("Data parsing error: " + e.getMessage());
            }
        }
    }

    private static class GetPersonalInfoTask extends AsyncTask<Void, Void, String> {
        private final ApiCallback<JSONObject> callback;
        private final String username;
        private Exception exception;

        GetPersonalInfoTask(String username, ApiCallback<JSONObject> callback) {
            this.callback = callback;
            this.username = username;
        }

        @Override
        protected String doInBackground(Void... voids) {
            HttpURLConnection conn = null;
            try {
                URL url = new URL(BASE_URL + "personal_info?username=" + username);
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);

                InputStream inputStream = conn.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                return response.toString();
            } catch (Exception e) {
                exception = e;
                return null;
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
        }

        @Override
        protected void onPostExecute(String result) {
            if (result == null) {
                callback.onError(exception != null ? exception.getMessage() : "Network error");
                return;
            }

            try {
                JSONObject jsonObject = new JSONObject(result);
                callback.onSuccess(jsonObject);
            } catch (JSONException e) {
                callback.onError("Data parsing error: " + e.getMessage());
            }
        }
    }

    private static int getCoverResourceId(String coverResId) {
        if ("book_android".equals(coverResId))
            return R.drawable.book_android;
        else if ("book_java".equals(coverResId))
            return R.drawable.book_java;
        else if ("book_data".equals(coverResId))
            return R.drawable.book_data;
        return R.drawable.book_default;
    }
}